package main

import (
	"errors"
	"fmt"
)

func fn1() {
	fmt.Println("开始")
	// 匿名自执行
	defer func() {
		fmt.Println("defer1")
		fmt.Println("defer2")
		fmt.Println("defer3")
	}()
	fmt.Println("结束")
}

// 调用方法返回0
func fn2() int {
	var a int
	defer func() {
		a++
	}()
	return a
}

// 调用方法返回1
func fn3() (a int) {
	defer func() {
		a++
	}()
	return a
}

func fp1() {
	fmt.Println("fp1")
}

func fp2() {
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println("err:", err)
		}
	}()
	panic("抛出了一个异常")
}

func fp3(a, b int) int {
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println("err:", err)
		}
	}()
	return a / b
}

func readFile(fileName string) error {
	if fileName == "main.go" {
		return nil
	} else {
		return errors.New("读取文件失败")
	}
}

func myFn() {
	defer func() {
		e := recover()
		if e != nil {
			fmt.Println("发送邮件给管理员", e)
		}
	}()

	err := readFile("xxx.go")
	if err != nil {
		panic(err)
	}
}

func main() {
	//1. defer的使用演示
	//2. defer在命名返回值和匿名返回,函数中表现不一样
	// 开始>结束>3>2>1
	//fmt.Println("开始")
	//defer fmt.Println(1)
	//defer fmt.Println(2)
	//defer fmt.Println(3)
	//fmt.Println("结束")

	//fn1()

	// 0
	//fmt.Println(fn2())
	// 1
	//fmt.Println(fn3())

	// GO语言中目前(1.12)是没有异常机制的, 但是使用panic/recover模式来处理异常
	// panic 可以在任何地方引发, 但是 recover 只有在 defer 调用的函数中有效
	//fp1()
	//fp2()
	//fmt.Println("结束")

	//fmt.Println(fp3(10, 0))
	//fmt.Println(fp3(10, 2))

	myFn()
	fmt.Println("继续执行...")
}
